package com.ruoyi.user.service.impl;

import com.ruoyi.user.domain.YmCartEntity;
import com.ruoyi.user.domain.YmOrderEntity;
import com.ruoyi.user.domain.YmProductEntity;
import com.ruoyi.user.enums.OrderStateEnum;
import com.ruoyi.user.enums.PayStateEnum;
import com.ruoyi.user.enums.ReqHandleExceptionEnum;
import com.ruoyi.user.mapper.YmCartMapper;
import com.ruoyi.user.mapper.YmOrderMapper;
import com.ruoyi.user.mapper.YmProductMapper;
import com.ruoyi.user.service.IYmOrderService;
import com.ruoyi.user.utils.DFUtil;
import com.ruoyi.user.utils.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

/**
 * Service业务层处理
 * 
 * @author zq
 * @date 2022-11-08
 */
@Service
@Slf4j
public class YmOrderServiceImpl implements IYmOrderService 
{
    @Autowired
    private YmOrderMapper ymOrderMapper;
    @Autowired
    private YmCartMapper ymCartMapper;
    @Autowired
    private YmProductMapper ymProductMapper;

    /**
     * 查询
     * 
     * @param id 主键
     * @return 
     */
    @Override
    public YmOrderEntity selectYmOrderById(Long id,Long uid)
    {
        return ymOrderMapper.selectYmOrderById(id,uid);
    }

    /**
     * 查询列表
     * 
     * @param ymOrderEntity 
     * @return 
     */
    @Override
    public List<YmOrderEntity> selectYmOrderList(YmOrderEntity ymOrderEntity)
    {
        return ymOrderMapper.selectYmOrderList(ymOrderEntity);
    }

    /**
     * 新增
     * 
     * @param ymOrderEntity 
     * @return 结果
     */
    @Override
    public int insertYmOrder(YmOrderEntity ymOrderEntity)
    {
        return ymOrderMapper.insertYmOrder(ymOrderEntity);
    }

    /**
     * 修改
     * 
     * @param ymOrderEntity 
     * @return 结果
     */
    @Override
    public int updateYmOrder(YmOrderEntity ymOrderEntity)
    {
        return ymOrderMapper.updateYmOrder(ymOrderEntity);
    }

    /**
     * 批量删除
     * 
     * @param ids 需要删除的主键
     * @return 结果
     */
    @Override
    public int deleteYmOrderByIds(Long[] ids)
    {
        return ymOrderMapper.deleteYmOrderByIds(ids);
    }

    /**
     * 删除信息
     * 
     * @param id 主键
     * @return 结果
     */
    @Override
    public int deleteYmOrderById(Long id)
    {
        return ymOrderMapper.deleteYmOrderById(id);
    }

    /**
     * 根据uid的商品加购情况生成对应的订单记录
     * @param ymOrderEntity
     * @return
     */
    @Override
    public int addOrder(YmOrderEntity ymOrderEntity) {
        Long uid = ymOrderEntity.getUid();
        /*
         先查询该用户当前是否存在未支付的订单，若存在提示先支付该订单，再创建新的订单
         原因：未支付的订单关联的商品是不会从购物车删除的（订单数量 > 0），创建新订单时回将原有的商品一起加入新订单中，不是想要的效果
               只有支付后的订单，paystate = 1，关联的加购商品其加购数量置为0，购物车列表不会渲染这些商品，生成新订单时不会再将这些商品
               加入新订单中

        List<YmOrderEntity> ymOrdersNotPay = ymOrderMapper.selectYmOrdersByUidAndPaystate(uid);
        if(!CollectionUtils.isEmpty(ymOrdersNotPay)){
            return -999;// 作为该用户当前存在未支付订单的标识
        }
         */

        // 先查出该uid对应的加购数量 > 0的商品（且未关联oid），计算对应的订单总价
        List<YmCartEntity> ymCarts = ymCartMapper.selectYmCartsByUidWithNumberGt0(uid);
        // 订单总价
        double orderPrice = 0;
        for (YmCartEntity ymCart : ymCarts) {
            Long pid = ymCart.getPid();
            Integer number = ymCart.getNumber();
            YmProductEntity product = ymProductMapper.selectYmProductById(pid);
            double price = product.getTprice().doubleValue();
            orderPrice += (price * number);
        }

        // 依据指定的规则，生成对应的订单流水号（年月日时分秒+6位随机数，共20位）
        String curDateStr = DFUtil.date2Str(new Date());// yyyy-MM-dd HH:mm:ss
        String[] splitArr1 = curDateStr.split(" ");
        String[] splitArr2 = splitArr1[0].substring(5).split("-");
        String[] splitArr3 = splitArr1[1].substring(3).split(":");
        String curTime = "";
        curTime = splitArr1[0].substring(0,4) + "" + splitArr2[0] + splitArr2[1] +  splitArr1[1].substring(0,2) + splitArr3[0] + splitArr3[1];
        int randomVal = (int)(Math.random() * (90 * 10000) + 100000);
        String orderSeqId = curTime + randomVal;//100000 - 999999 左闭右开

        // 订单创建时间 如：2022-11-09 20:34:56
        String creatTime = splitArr1[0].substring(0,4) + "-" + splitArr2[0] + "-" + splitArr2[1] +
                " " + splitArr1[1].substring(0,2) + ":" + splitArr3[0] + ":" + splitArr3[1];
        System.out.println("curTime = " + curTime + ", randomVal = " + randomVal + ",createTime = " + creatTime);

        // 订单类型，默认为外卖 1：外卖  0：自取
        Integer otype = ymOrderEntity.getOtype();

        // 收获状态 0：未收货 1：已收货 2：退订（未支付，可退单的） 3：禁用   订单状态 0：正常 1：禁用
        Integer paystate = PayStateEnum.UN_PAY.getCode();
        Integer ostate = OrderStateEnum.TO_PAY.getCode();

        YmOrderEntity ymOrder = new YmOrderEntity();
        ymOrder.setOnumber(orderSeqId);
        ymOrder.setOprice(orderPrice);
        ymOrder.setOtype(otype);
        ymOrder.setOstate(ostate);
        ymOrder.setUid(uid);
        ymOrder.setPaystate(paystate);
        ymOrder.setCreatetime(creatTime);
        // 支付时间由支付的那一时刻确认 TODO

        // 创建订单的同时，将加购的这些商品关联上对应的订单，便于后续查询订单列表时查出所关联的商品
        ymOrderMapper.insertYmOrder(ymOrder);
        Long orderId = ymOrder.getId();
        System.out.println("orderId = " + orderId);

        return ymCartMapper.updateOrderIdForOrderRender(orderId,uid);
    }

    /**
     * 根据uid和ostate查出所关联的所有订单
     * @param uid ostate
     * @return
     */
    @Override
    public List<YmOrderEntity> selectYmOrdersByUidAndOstate(Long uid,String ostate) {
        return ymOrderMapper.selectYmOrdersByUidAndOstate(uid,ostate);
    }

    /**
     * 根据orderId对订单作退订处理
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public boolean cancelOrder(Long id) {
        // 先到购物车表中将orderId关联的所有加购商品的oid置为null，再到订单表中删除orderId对应的订单记录
        try {
            // 将用户uid置为null
            ymCartMapper.updateYmCartByOIdForNull(id);
//        opResult = ymOrderMapper.deleteYmOrderById(id);
            // 更新订单为取消
            ymOrderMapper.updateYmOrderState(id, PayStateEnum.CANCEL.getCode(), OrderStateEnum.CANCEL_ORDER.getCode());
        }catch (Exception e){
            log.info("订单取消异常:",e);
            return false;
        }
        return true;
    }


    /**
     * 查询未支付订单
     * @return
     */
    @Override
    public boolean selectUnPayOrderList(long uid,long oid) {
        // 查询未支付数量，不包含禁用
        List<YmOrderEntity> ymOrderEntityList = ymOrderMapper.selectUnPayOrderList(uid, oid);
        return ymOrderEntityList.size() == 0;
    }

    @Override
    public JsonData payOrder(YmOrderEntity ymOrderEntity) {
        // 先查询是否有订单未支付
        log.info("ymOrderEnity:{}",ymOrderEntity);
        boolean isPay = selectUnPayOrderList(ymOrderEntity.getUid(),ymOrderEntity.getId());
        // 如果有订单未支付，则必须先进行支付
        if (!isPay){
            return JsonData.buildError(ReqHandleExceptionEnum.EXIST_ORDER_NOT_PAY);
        }
        // 根据订单流水号查找订单
        log.info("ymOrderEntity:{}",ymOrderEntity);
        YmOrderEntity ymOrder = selectYmOrderById(ymOrderEntity.getId(), ymOrderEntity.getUid());
        // 修改订单状态为已支付，修改订单为未收货
        ymOrder.setOstate(OrderStateEnum.SENDING.getCode());
        ymOrder.setPaystate(PayStateEnum.PAYED.getCode());
        // 更新
        int updateYmOrderRes = updateYmOrder(ymOrder);
        log.info("insertYmOrderRes:{}",updateYmOrderRes);
        return JsonData.buildSuccess();
    }

    @Override
    public JsonData receive(YmOrderEntity ymOrderEntity) {
        // 根据订单流水号查找订单
        log.info("ymOrderEntity:{}",ymOrderEntity);
        YmOrderEntity ymOrder = selectYmOrderById(ymOrderEntity.getId(),ymOrderEntity.getUid());
        // 修改订单状态为已收货
        ymOrder.setOstate(OrderStateEnum.RECEIVED.getCode());
        // 更新
        int updateYmOrderRes = updateYmOrder(ymOrder);
        log.info("insertYmOrderRes:{}",updateYmOrderRes);
        return JsonData.buildSuccess();
    }
}
